package com.microservice.auth.controller;

import com.microservice.api.common.Result;
import com.microservice.common.util.CaptchaUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 验证码控制器
 */
@Slf4j
@RestController
@RequestMapping("/auth/captcha")
public class CaptchaController {
    
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    
    // 验证码在Redis中的key前缀
    private static final String CAPTCHA_PREFIX = "captcha:";
    
    // 验证码有效期（分钟）
    private static final long CAPTCHA_EXPIRE_MINUTES = 5;
    
    /**
     * 生成验证码图片
     * GET /auth/captcha/image
     * 
     * @return 验证码图片（PNG格式）
     */
    @GetMapping("/image")
    public ResponseEntity<byte[]> getCaptchaImage() {
        try {
            // 生成验证码文本
            String captchaText = CaptchaUtil.generateCaptchaText();
            
            // 生成唯一的验证码key
            String captchaKey = UUID.randomUUID().toString().replace("-", "");
            
            // 将验证码存入Redis，设置5分钟过期（不区分大小写）
            stringRedisTemplate.opsForValue().set(
                CAPTCHA_PREFIX + captchaKey, 
                captchaText.toUpperCase(), 
                CAPTCHA_EXPIRE_MINUTES, 
                TimeUnit.MINUTES
            );
            
            log.info("生成验证码: key={}, text={}", captchaKey, captchaText);
            
            // 生成验证码图片
            byte[] imageBytes = CaptchaUtil.generateCaptchaImage(captchaText);
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentLength(imageBytes.length);
            // 禁止缓存
            headers.setCacheControl("no-cache, no-store, must-revalidate");
            headers.setPragma("no-cache");
            headers.setExpires(0);
            // 在响应头中返回验证码key
            headers.add("Captcha-Key", captchaKey);
            
            return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
            
        } catch (Exception e) {
            log.error("生成验证码失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    /**
     * 获取验证码key（用于前端需要先获取key再显示图片的场景）
     * GET /auth/captcha/key
     * 
     * @return 验证码key
     */
    @GetMapping("/key")
    public Result<Map<String, String>> getCaptchaKey() {
        try {
            // 生成验证码文本
            String captchaText = CaptchaUtil.generateCaptchaText();
            
            // 生成唯一的验证码key
            String captchaKey = UUID.randomUUID().toString().replace("-", "");
            
            // 将验证码存入Redis（不区分大小写）
            stringRedisTemplate.opsForValue().set(
                CAPTCHA_PREFIX + captchaKey, 
                captchaText.toUpperCase(), 
                CAPTCHA_EXPIRE_MINUTES, 
                TimeUnit.MINUTES
            );
            
            log.info("生成验证码key: key={}, text={}", captchaKey, captchaText);
            
            Map<String, String> result = new HashMap<>();
            result.put("captchaKey", captchaKey);
            result.put("captchaImage", "/auth-mbs/auth/captcha/image/" + captchaKey);
            
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("生成验证码key失败", e);
            return Result.error("生成验证码失败");
        }
    }
    
    /**
     * 根据key获取验证码图片
     * GET /auth/captcha/image/{key}
     * 
     * @param key 验证码key
     * @return 验证码图片
     */
    @GetMapping("/image/{key}")
    public ResponseEntity<byte[]> getCaptchaImageByKey(@PathVariable String key) {
        try {
            // 从Redis获取验证码文本
            String captchaText = stringRedisTemplate.opsForValue().get(CAPTCHA_PREFIX + key);
            
            if (captchaText == null) {
                log.warn("验证码不存在或已过期: key={}", key);
                return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
            }
            
            // 生成验证码图片
            byte[] imageBytes = CaptchaUtil.generateCaptchaImage(captchaText);
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_PNG);
            headers.setContentLength(imageBytes.length);
            // 禁止缓存
            headers.setCacheControl("no-cache, no-store, must-revalidate");
            headers.setPragma("no-cache");
            headers.setExpires(0);
            
            return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
            
        } catch (Exception e) {
            log.error("获取验证码图片失败: key={}", key, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    /**
     * 验证验证码是否正确（内部接口，供其他服务调用）
     * GET /auth/captcha/verify?key=xxx&code=xxx
     * 
     * @param key 验证码key
     * @param code 用户输入的验证码
     * @return 验证结果
     */
    @GetMapping("/verify")
    public Result<Boolean> verifyCaptcha(
            @RequestParam String key,
            @RequestParam String code) {
        try {
            String captchaText = stringRedisTemplate.opsForValue().get(CAPTCHA_PREFIX + key);
            
            if (captchaText == null) {
                return Result.error("验证码不存在或已过期");
            }
            
            boolean isValid = captchaText.equalsIgnoreCase(code);
            
            if (isValid) {
                // 验证成功后删除验证码，防止重复使用
                stringRedisTemplate.delete(CAPTCHA_PREFIX + key);
            }
            
            return Result.success(isValid);
            
        } catch (Exception e) {
            log.error("验证验证码失败", e);
            return Result.error("验证失败");
        }
    }
}
